// 版权归Go作者所有。版权所有。
// 此源代码的使用受BSD样式的约束
// 可以在许可证文件中找到的许可证。

package ssa

import (
	"cmd/internal/src"
	"math"
)

// biasedSparseMap是J和K（含J和K）之间整数的sparseMap，
// 其中J可能略大于零（K-J可能比J小得多）。
// （激励用例是单个函数的语句行号。）
// 并非SparseMap的所有功能都会导出，而且处理SparseMap也很容易
// 像一个稀疏集一样的稀疏映射。
type biasedSparseMap struct {
	s     *sparseMap
	first int
}

// newBiasedSparseMap返回一个新的biasedSparseMap，其值介于第一个和最后一个（包括第一个和最后一个）之间。
func newBiasedSparseMap(first, last int) *biasedSparseMap {
	if first > last {
		return &biasedSparseMap{first: math.MaxInt32, s: nil}
	}
	return &biasedSparseMap{first: first, s: newSparseMap(1 + last - first)}
}

// cap返回的密钥比对s有效的最大密钥多一个
func (s *biasedSparseMap) cap() int {
	if s == nil || s.s == nil {
		return 0
	}
	return s.s.cap() + int(s.first)
}

// size返回存储在s中的条目数
func (s *biasedSparseMap) size() int {
	if s == nil || s.s == nil {
		return 0
	}
	return s.s.size()
}

// 包含报告x是否是s中的键
func (s *biasedSparseMap) contains(x uint) bool {
	if s == nil || s.s == nil {
		return false
	}
	if int(x) < s.first {
		return false
	}
	if int(x) >= s.cap() {
		return false
	}
	return s.s.contains(ID(int(x) - s.first))
}

// get返回键x的值s映射，如果是，则返回-1
// x未映射或超出s的范围。
func (s *biasedSparseMap) get(x uint) int32 {
	if s == nil || s.s == nil {
		return -1
	}
	if int(x) < s.first {
		return -1
	}
	if int(x) >= s.cap() {
		return -1
	}
	return s.s.get(ID(int(x) - s.first))
}

// getEntry返回存储在s中的第i个键和值，
// 其中0<=i<s.尺寸（）
func (s *biasedSparseMap) getEntry(i int) (x uint, v int32) {
	e := s.s.contents()[i]
	x = uint(int(e.key) + s.first)
	v = e.val
	return
}

// 在s中添加插入x->0，前提是x在s中存储的键的范围内。
func (s *biasedSparseMap) add(x uint) {
	if int(x) < s.first || int(x) >= s.cap() {
		return
	}
	s.s.set(ID(int(x)-s.first), 0, src.NoXPos)
}

// 在s中添加插入x->v，前提是x在s中存储的键的范围内。
func (s *biasedSparseMap) set(x uint, v int32) {
	if int(x) < s.first || int(x) >= s.cap() {
		return
	}
	s.s.set(ID(int(x)-s.first), v, src.NoXPos)
}

// 移除从s中移除键x。
func (s *biasedSparseMap) remove(x uint) {
	if int(x) < s.first || int(x) >= s.cap() {
		return
	}
	s.s.remove(ID(int(x) - s.first))
}

func (s *biasedSparseMap) clear() {
	if s.s != nil {
		s.s.clear()
	}
}
